package redis;





import org.apache.commons.pool2.BasePooledObjectFactory;
import org.apache.commons.pool2.PooledObject;
import org.apache.commons.pool2.impl.DefaultPooledObject;
import org.apache.commons.pool2.impl.GenericObjectPool;
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
import redis.clients.jedis.Jedis;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;


/**
 *
 * EWrapper连接池工厂
 * @author shane
 *
 */
public class JedisPoolFactory extends BasePooledObjectFactory<Jedis>{

	private String ip;
	private int port;
    private String pass;

    public JedisPoolFactory() {
        ip = "10.161.228.88";
        port = 6379;
        pass = "test";
    }

    public static void main(String[] args) throws InterruptedException {
        GenericObjectPoolConfig config = new GenericObjectPoolConfig();
		config.setMaxWaitMillis(2000);
		config.setMinIdle(1);
		config.setMaxIdle(3);
		config.setMaxTotal(5);
        config.setTestOnBorrow(true);
        config.setTestOnReturn(true);

        /**
         * 销毁到minidle
         */
        config.setSoftMinEvictableIdleTimeMillis(3000);

        /**
         * 销毁所有
         */
     //   config.setMinEvictableIdleTimeMillis(3000);

        // 词句是必须的，否则（Soft）MinEvictableIdleTimeMillis不生效
        config.setTimeBetweenEvictionRunsMillis(100);

        GenericObjectPool<Jedis> objectPool = new GenericObjectPool<Jedis>(new JedisPoolFactory(), config);

        List<Jedis> list = new ArrayList<>();

        /**
         * 等待第一个连接初始化，因为minidle＝1
         */
        Thread.sleep(5000);

        /**
         * 申请六个资源，且不归还，等待报错
         */
        try {
            for(int i=0; i<6; ++i) {
                Jedis jedis = objectPool.borrowObject();
            //    objectPool.returnObject(jedis);
                list.add(jedis);
            }

        } catch (Exception e) {
            System.out.println(e.getMessage() + new Date());
        }

        /**
         * 清理，查看clear－destroy情况
         */
        // 不归还的话，clear无效
        for(Jedis jedis : list) {
            objectPool.returnObject(jedis);
        }
        objectPool.clear();
        list.clear();

        /**
         * 休息5s
         */
        Thread.sleep(5000);

        /**
         * 申请5个连接，然后一起归还，5大于maxidle＝3的2个对象应该被立即销毁，然后等3s后，到minidle＝1的2个对象被销毁
         */
        try {
            for(int i=0; i<5; ++i) {
                Jedis jedis = objectPool.borrowObject();
                list.add(jedis);
                //    objectPool.returnObject(jedis);
            }

            for(Jedis jedis : list) {
                objectPool.returnObject(jedis);
            }

            // 等待对象销毁
            Thread.sleep(10000);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

	public JedisPoolFactory(String ip, int port, String pass) {
		this.ip = ip;
		this.port = port;
        this.pass = pass;
	}

	@Override
	public Jedis create() throws Exception {
        Jedis jedis = new Jedis(ip, port, 10000);
        jedis.auth("test");

        return jedis;
	}

    @Override
    public PooledObject<Jedis> wrap(Jedis jedis) {
        System.out.println("创建" + new Date());
        return new DefaultPooledObject<Jedis>(jedis);
    }
//
//    @Override
//	public PooledObject<AbstractWrapper> wrap(AbstractWrapper wrapper) {
//		return new DefaultPooledObject<AbstractWrapper>(wrapper);
//	}
//
    /**
     * 对象激活(borrowObject时触发）
     *
     * @param pooledObject
     */
    @Override
    public void activateObject(PooledObject<Jedis> pooledObject) throws Exception {
        System.out.println("申请" + new Date());
        super.activateObject(pooledObject);
    }


    /**
     * 对象销毁
     * @param pooledObject
     */
    @Override
    public void destroyObject(PooledObject<Jedis> pooledObject) throws Exception {
        System.out.println("销毁" + new Date());
        Jedis jedis = pooledObject.getObject();
        jedis.close();
        super.destroyObject(pooledObject);
    }


    /**
     * 验证对象有效性
     * @param
     * @return
     */
    @Override
    public boolean validateObject(PooledObject<Jedis> pooledObject) {
        System.out.println("validate");
        return true;
    }

    public void passivateObject(PooledObject<Jedis> p) throws Exception {
        System.out.println("passivate");
        super.passivateObject(p);
    }

}
